package _01_String;
/**
 * java.lang.String 是字符串
 * 
 * 它的底层是一个字符数组,所以它的很多特性就是数组的特性
 * 
 * 1.字符串一旦被创建,这个字符串对象就不可更改了
 * 
 * 2.为了提升字符串的访问速度, java 虚拟机采用了一种缓存的技术,String 是一个引用数据类型,那么String 的值应该保存在堆内存吧!
 * 		但是字符串不一样,字符串对象会在静态区有一个字符串常量池
 * 
 * 3.在程序执行中,如果程序要用到某一个字符串,比如 ("abc") ,虚拟机首先会去字符串常量池中搜索,有没有这个字符串
 * 		如果已经有了,就直接指向这个字符串,不需要再创建一个
 * 		如果没有,就创建一个,然后再指向
 * 
 * 
 * @author lenovo
 * @Date 2020年7月15日
 * @Time 下午6:16:58
 */
public class String_01 {

	public static void main(String[] args) {
		// 创建一个abc 字符串对象,直接保存在常量池中,然后将内存地址赋值给变量 S1
		// 尽管没有 new 但是s1 还是指向字符串对象
		String s1 = "abd";
		// s1 是 main 方法中局部变量,并且没有使用 final 修饰,所以可以更改s1 的值
		// 因为 s1 只是保存了一个内存地址 , 所以 s1 可以重新赋值一个新的内存地址
		// 但是 abc 对象,更改不了了
		s1 = "def";

		String s2 = "Hello";
		String s3 = "Hello";
		String s4 = "hello";
		System.out.println(s2 == s3);// true
		System.out.println(s3 == s4);// false
		// 创建两个对象,一个Hello 一个 hello

		// true 比较值,因为 String 覆写了
		System.out.println(s2.equals(s3));// true

		String s5 = new String("abc");
		String s6 = new String("abc");
		// false 因为这种方式, s5 和 s6 分别指向堆内存,堆内存再指向数据
		System.out.println(s5 == s6);// false
		System.out.println(s5.equals(s6));// true

	}

}
